
<!DOCTYPE HTML>
<html lang="" >
    <head>
        <meta charset="UTF-8">
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <title>Java InvocationHandler 实现动态代理 · 寒江蓑笠的博客</title>
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="description" content="">
        <meta name="generator" content="GitBook 3.2.3">
        
        
        
    
    <link rel="stylesheet" href="../../gitbook/style.css">

    
            
                
                <link rel="stylesheet" href="../../gitbook/gitbook-plugin-expandable-chapters/expandable-chapters.css">
                
            
                
                <link rel="stylesheet" href="../../gitbook/gitbook-plugin-highlight/website.css">
                
            
                
                <link rel="stylesheet" href="../../gitbook/gitbook-plugin-search/search.css">
                
            
                
                <link rel="stylesheet" href="../../gitbook/gitbook-plugin-fontsettings/website.css">
                
            
        

    

    
        
    
        
    
        
    
        
    
        
    
        
    

        
    
    
    <meta name="HandheldFriendly" content="true"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <link rel="apple-touch-icon-precomposed" sizes="152x152" href="../../gitbook/images/apple-touch-icon-precomposed-152.png">
    <link rel="shortcut icon" href="../../gitbook/images/favicon.ico" type="image/x-icon">

    
    <link rel="next" href="java-basic-try-catch-finally.html" />
    
    
    <link rel="prev" href="java-basic-concurrent-map-collection.html" />
    

    </head>
    <body>
        
<div class="book">
    <div class="book-summary">
        
            
<div id="book-search-input" role="search">
    <input type="text" placeholder="Type to search" />
</div>

            
                <nav role="navigation">
                


<ul class="summary">
    
    

    

    
        
        
    
        <li class="chapter " data-level="1.1" data-path="../../">
            
                <a href="../../">
            
                    
                    Java
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.1.1" data-path="java-basic-joor.html">
            
                <a href="java-basic-joor.html">
            
                    
                    Java 基础 -- 使用 JOOR 实现反射
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.2" data-path="java-basic-annotation.html">
            
                <a href="java-basic-annotation.html">
            
                    
                    Java基础 -- 注解
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.3" data-path="java-basic-threadlocal.html">
            
                <a href="java-basic-threadlocal.html">
            
                    
                    Java 基础 -- ThreadLocal
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.4" data-path="java-development-skills-get-stacktrace.html">
            
                <a href="java-development-skills-get-stacktrace.html">
            
                    
                    Java 开发技巧 -- 获取 Java 的调用栈
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.5" data-path="java-basic-concurrent-map-collection.html">
            
                <a href="java-basic-concurrent-map-collection.html">
            
                    
                    Java 基础 -- 并发集合的使用
            
                </a>
            

            
        </li>
    
        <li class="chapter active" data-level="1.1.6" data-path="java-dynamic-proxy-invocationhandler-demo.html">
            
                <a href="java-dynamic-proxy-invocationhandler-demo.html">
            
                    
                    Java InvocationHandler 实现动态代理
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.7" data-path="java-basic-try-catch-finally.html">
            
                <a href="java-basic-try-catch-finally.html">
            
                    
                    Java 基础 -- 深入理解 try catch finally
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.8" data-path="java-basic-reflect.html">
            
                <a href="java-basic-reflect.html">
            
                    
                    Java 基础 -- 反射
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.9" data-path="java-basic-io-stream.html">
            
                <a href="java-basic-io-stream.html">
            
                    
                    Java IO -- IO流的概念和分类
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.10" data-path="java-basic-final.html">
            
                <a href="java-basic-final.html">
            
                    
                    Java 基础 -- 深入理解 final 修饰符
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.11" data-path="java-basic-memory-manage-constructor.html">
            
                <a href="java-basic-memory-manage-constructor.html">
            
                    
                    Java 内存管理 -- 父子实例的内存控制
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.12" data-path="java-basic-memory-manage-inherit-object.html">
            
                <a href="java-basic-memory-manage-inherit-object.html">
            
                    
                    Java 内存管理 -- 构造方法
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.13" data-path="java-basic-memory-manage-memory-area.html">
            
                <a href="java-basic-memory-manage-memory-area.html">
            
                    
                    Java 内存管理 -- 内存区域的划分
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.14" data-path="java-basic-memory-manage-variable.html">
            
                <a href="java-basic-memory-manage-variable.html">
            
                    
                    Java 内存管理 -- 变量的内存管理
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.15" data-path="java-basic-knowledge-generic.html">
            
                <a href="java-basic-knowledge-generic.html">
            
                    
                    Java 基础 -- 范型
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.16" data-path="java-basic-knowledge-auto-boxing.html">
            
                <a href="java-basic-knowledge-auto-boxing.html">
            
                    
                    Java 基础 -- 关于自动装箱和拆箱机制
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.17" data-path="java-basic-knowledge-parameter-passing.html">
            
                <a href="java-basic-knowledge-parameter-passing.html">
            
                    
                    Java 基础 -- 值传递、引用传递和参数传递
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.18" data-path="java-basic-stringbuilder-stringbuffer.html">
            
                <a href="java-basic-stringbuilder-stringbuffer.html">
            
                    
                    Java 基础 -- StringBuilder 和 StringBuffer
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.19" data-path="java-basic-knowledge-about-string.html">
            
                <a href="java-basic-knowledge-about-string.html">
            
                    
                    Java 基础 -- 深入理解 String
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.1.20" data-path="java-basic-linkedhashmap.html">
            
                <a href="java-basic-linkedhashmap.html">
            
                    
                    Java 基础 -- LinkedHashMap 的使用和原理
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

    

    <li class="divider"></li>

    <li>
        <a href="https://www.gitbook.com" target="blank" class="gitbook-link">
            Published with GitBook
        </a>
    </li>
</ul>


                </nav>
            
        
    </div>

    <div class="book-body">
        
            <div class="body-inner">
                
                    

<div class="book-header" role="navigation">
    

    <!-- Title -->
    <h1>
        <i class="fa fa-circle-o-notch fa-spin"></i>
        <a href="../.." >Java InvocationHandler 实现动态代理</a>
    </h1>
</div>




                    <div class="page-wrapper" tabindex="-1" role="main">
                        <div class="page-inner">
                            
<div id="book-search-results">
    <div class="search-noresults">
    
                                <section class="normal markdown-section">
                                
                                <hr>
<p>title: Java InvocationHandler &#x5B9E;&#x73B0;&#x52A8;&#x6001;&#x4EE3;&#x7406;
categories: Java
comments: true
tags: [Java, &#x52A8;&#x6001;&#x4EE3;&#x7406;]
description: &#x4ECB;&#x7ECD;&#x4F7F;&#x7528; InvocationHandler &#x5B9E;&#x73B0; Java &#x52A8;&#x6001;&#x4EE3;&#x7406;&#x53CA;&#x5176;&#x539F;&#x7406;&#x4ECB;&#x7ECD;</p>
<h2 id="date-2015-4-10-100000">date: 2015-4-10 10:00:00</h2>
<h2 id="&#x6982;&#x8FF0;">&#x6982;&#x8FF0;</h2>
<p>&#x4EE3;&#x7406;&#x662F;&#x8BBE;&#x8BA1;&#x6A21;&#x5F0F;&#x7684;&#x4E00;&#x79CD;&#xFF0C;&#x8BBE;&#x8BA1;&#x6A21;&#x5F0F;&#x662F;&#x6307;&#x8C03;&#x7528;&#x8005;&#x5E76;&#x4E0D;&#x76F4;&#x63A5;&#x8C03;&#x7528;&#x5B9E;&#x9645;&#x7684;&#x5BF9;&#x8C61;&#xFF0C;&#x800C;&#x662F;&#x901A;&#x8FC7;&#x8C03;&#x7528;&#x4EE3;&#x7406;&#xFF0C;&#x6765;&#x95F4;&#x63A5;&#x7684;&#x8C03;&#x7528;&#x5B9E;&#x9645;&#x7684;&#x5BF9;&#x8C61;&#x3002;&#x4EE3;&#x7406;&#x7C7B;&#x4E0E;&#x771F;&#x6B63;&#x5B9E;&#x73B0;&#x7684;&#x7C7B;&#x90FD;&#x662F;&#x7EE7;&#x627F;&#x6216;&#x8005;&#x5B9E;&#x73B0;&#x4E00;&#x4E2A;&#x76F8;&#x540C;&#x7684;&#x7C7B;&#x6216;&#x8FD9;&#x63A5;&#x53E3;&#xFF0C;&#x8FD9;&#x6837;&#x7684;&#x597D;&#x5904;&#x5728;&#x4E8E;&#x4EE3;&#x7406;&#x7C7B;&#x53EF;&#x4EE5;&#x4E0E;&#x5B9E;&#x9645;&#x7684;&#x7C7B;&#x6709;&#x76F8;&#x540C;&#x7684;&#x65B9;&#x6CD5;&#xFF0C;&#x53EF;&#x4EE5;&#x4FDD;&#x8BC1;&#x5BA2;&#x6237;&#x7AEF;&#x4F7F;&#x7528;&#x7684;&#x900F;&#x660E;&#x6027;&#x3002;
&#x65E2;&#x7136;&#x6709;&#x52A8;&#x6001;&#x4EE3;&#x7406;&#xFF0C;&#x90A3;&#x4E48;&#x76F8;&#x5BF9;&#x5E94;&#x7684;&#x80AF;&#x5B9A;&#x4E5F;&#x5B58;&#x5728;&#x9759;&#x6001;&#x4EE3;&#x7406;&#x3002;</p>
<ul>
<li>&#x9759;&#x6001;&#x4EE3;&#x7406;&#xFF1A;&#x7531;&#x7A0B;&#x5E8F;&#x5458;&#x624B;&#x5DE5;&#x7F16;&#x5199;&#x4EE3;&#x7406;&#x7C7B;&#x3002;</li>
<li>&#x52A8;&#x6001;&#x4EE3;&#x7406;&#xFF1A;&#x5728;&#x7A0B;&#x5E8F;&#x8FD0;&#x884C;&#x65F6;&#x8FD0;&#x7528;&#x53CD;&#x5C04;&#x673A;&#x5236;&#x52A8;&#x6001;&#x521B;&#x5EFA;&#x751F;&#x6210;&#x4EE3;&#x7406;&#x7C7B;&#x3002;</li>
</ul>
<p>&#x9759;&#x6001;&#x4EE3;&#x7406;&#x7565;&#x53BB;&#x4E0D;&#x4ECB;&#x7ECD;&#xFF0C;&#x4E0B;&#x9762;&#x4ECB;&#x7ECD;&#x4E00;&#x4E0B;&#x52A8;&#x6001;&#x4EE3;&#x7406;&#x7684;&#x5B9E;&#x73B0;&#x3002;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;JDK&#x7684; InvocationHandler &#x548C; Proxy &#x5B9E;&#x73B0;&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x901A;&#x8FC7; CGLIB &#x6765;&#x5B9E;&#x73B0;&#xFF0C;&#x4ED6;&#x4EEC;&#x7684;&#x533A;&#x522B;&#x540E;&#x9762;&#x4ECB;&#x7ECD;&#xFF0C;&#x8FD9;&#x91CC;&#x4E4B;&#x4ECB;&#x7ECD; InvocationHandler &#x548C; Proxy &#x7684;&#x5B9E;&#x73B0;&#x3002;</p>
<h2 id="&#x52A8;&#x6001;&#x4EE3;&#x7406;">&#x52A8;&#x6001;&#x4EE3;&#x7406;</h2>
<p>Java&#x7684;&#x52A8;&#x6001;&#x4EE3;&#x7406;&#x4E3B;&#x8981;&#x6D89;&#x53CA;&#x4E24;&#x4E2A;&#x7C7B;&#xFF0C;<code>Proxy</code> &#x548C; <code>InvocationHandler</code>&#x3002;</p>
<ul>
<li><code>Proxy</code> &#x7528;&#x4E8E;&#x4E3A;&#x63A5;&#x53E3;&#x751F;&#x6210;&#x52A8;&#x6001;&#x4EE3;&#x7406;&#x7C7B;&#x53CA;&#x5176;&#x5BF9;&#x8C61;&#x3002;</li>
<li><code>InvocationHandler</code> &#x63D0;&#x4F9B;&#x4E86; <code>invoke</code> &#x65B9;&#x6CD5;&#xFF0C;&#x8D1F;&#x8D23;&#x96C6;&#x4E2D;&#x5904;&#x7406;&#x52A8;&#x6001;&#x4EE3;&#x7406;&#x7C7B;&#x4E0A;&#x7684;&#x6240;&#x6709;&#x65B9;&#x6CD5;&#x8C03;&#x7528;&#x3002;</li>
</ul>
<p>&#x4EE3;&#x7406;&#x7C7B;&#x4F1A;&#x8D1F;&#x8D23;&#x5C06;&#x6240;&#x6709;&#x7684;&#x65B9;&#x6CD5;&#x8C03;&#x7528;&#x5206;&#x6D3E;&#x5230;&#x59D4;&#x6258;&#x5BF9;&#x8C61;&#x4E0A;&#x53CD;&#x5C04;&#x6267;&#x884C;&#xFF0C;&#x5728;&#x5206;&#x6D3E;&#x6267;&#x884C;&#x7684;&#x8FC7;&#x7A0B;&#x4E2D;&#xFF0C;&#x5F00;&#x53D1;&#x4EBA;&#x5458;&#x8FD8;&#x53EF;&#x4EE5;&#x6309;&#x9700;&#x8C03;&#x6574;&#x59D4;&#x6258;&#x7C7B;&#x5BF9;&#x8C61;&#x53CA;&#x5176;&#x529F;&#x80FD;&#xFF0C;&#x8FD9;&#x662F;&#x4E00;&#x5957;&#x975E;&#x5E38;&#x7075;&#x6D3B;&#x6709;&#x5F39;&#x6027;&#x7684;&#x4EE3;&#x7406;&#x6846;&#x67B6;&#x3002;
&#x4E0B;&#x9762;&#x901A;&#x8FC7;&#x4E00;&#x4E2A;&#x5B9E;&#x4F8B;&#x6765;&#x6F14;&#x793A;&#x4E00;&#x4E0B;&#xFF1A;</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Fruit</span> </span>{
    <span class="hljs-function">String <span class="hljs-title">getName</span><span class="hljs-params">()</span></span>;
}
</code></pre>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Apple</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Fruit</span> </span>{
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getName</span><span class="hljs-params">()</span> </span>{
        Log.e(<span class="hljs-string">&quot;Test&quot;</span>,<span class="hljs-string">&quot;I am apple!&quot;</span>);
        <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;Apple&quot;</span>;
    }
}
</code></pre>
<pre><code class="lang-java">    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">testProxy</span><span class="hljs-params">()</span></span>{

        <span class="hljs-keyword">final</span> Apple apple = <span class="hljs-keyword">new</span> Apple();

        InvocationHandler invocationHandler = <span class="hljs-keyword">new</span> InvocationHandler() {
            <span class="hljs-meta">@Override</span>
            <span class="hljs-function"><span class="hljs-keyword">public</span> Object <span class="hljs-title">invoke</span><span class="hljs-params">(Object proxy, Method method, Object[] args)</span> <span class="hljs-keyword">throws</span> Throwable </span>{
                <span class="hljs-keyword">if</span>(<span class="hljs-string">&quot;getName&quot;</span>.equals(method.getName())){
                    Log.e(<span class="hljs-string">&quot;Test&quot;</span>,<span class="hljs-string">&quot;Let Apple introduce himself.&quot;</span>);
                    <span class="hljs-comment">// &#x8FD4;&#x56DE;&#x65B9;&#x6CD5;&#x7684;&#x6267;&#x884C;&#x7ED3;&#x679C;</span>
                    Object result = method.invoke(apple, args);
                    Log.e(<span class="hljs-string">&quot;Test&quot;</span>,<span class="hljs-string">&quot;Thank you!&quot;</span>);
                    <span class="hljs-keyword">return</span> result;
                }
                <span class="hljs-keyword">return</span> <span class="hljs-keyword">null</span>;
            }
        };

        Fruit newApple = (Fruit) Proxy.newProxyInstance(invocationHandler.getClass().getClassLoader(),
                apple.getClass().getInterfaces(),invocationHandler);
        String name = newApple.getName();
        Log.e(<span class="hljs-string">&quot;Test&quot;</span>,newApple.getClass().getName() + <span class="hljs-string">&quot;,name = &quot;</span> + name);

    }
</code></pre>
<p>&#x7ED3;&#x679C;&#xFF1A;</p>
<pre><code>E/Test: Let Apple introduce himself.
E/Test: I am apple!
E/Test: Thank you!
E/Test: $Proxy0,name = Apple
</code></pre><p>&#x5B9E;&#x73B0;&#x52A8;&#x6001;&#x4EE3;&#x7406;&#x7684;&#x65B9;&#x6CD5;&#xFF1A;</p>
<ol>
<li>&#x83B7;&#x53D6;&#x9700;&#x8981;&#x4EE3;&#x7406;&#x7684;&#x7C7B;&#x7684;&#x5B9E;&#x4F8B;&#x3002;</li>
<li>&#x5B9E;&#x73B0; InvocationHandler &#x63A5;&#x53E3;&#x521B;&#x5EFA;&#x81EA;&#x5DF1;&#x7684;&#x8C03;&#x7528;&#x5904;&#x7406;&#x5668;&#xFF0C;&#x5B9E;&#x73B0; invoke &#x65B9;&#x6CD5;&#xFF0C;&#x901A;&#x8FC7; <code>method.invoke(apple, args)</code> &#x8C03;&#x7528;&#x88AB;&#x4EE3;&#x7406;&#x7C7B;&#x3002;</li>
<li>&#x901A;&#x8FC7; Proxy.newProxyInstance &#x65B9;&#x6CD5;&#x5E76;&#x6307;&#x5B9A; ClassLoader &#x5BF9;&#x8C61;&#x548C;&#x4E00;&#x7EC4; interface &#x4EE5;&#x53CA; &#x6307;&#x5B9A; invocationHandler &#x5BF9;&#x8C61;&#x6765;&#x521B;&#x5EFA;&#x52A8;&#x6001;&#x4EE3;&#x7406;&#x7C7B;&#x3002;</li>
<li>&#x901A;&#x8FC7;&#x53CD;&#x5C04;&#x673A;&#x5236;&#x83B7;&#x5F97;&#x52A8;&#x6001;&#x4EE3;&#x7406;&#x7C7B;&#x7684;&#x6784;&#x9020;&#x51FD;&#x6570;&#x3002;</li>
<li>&#x901A;&#x8FC7;&#x6784;&#x9020;&#x51FD;&#x6570;&#x521B;&#x5EFA;&#x52A8;&#x6001;&#x4EE3;&#x7406;&#x7C7B;&#x5B9E;&#x4F8B;&#xFF0C;&#x6784;&#x9020;&#x65F6;&#x8C03;&#x7528;&#x5904;&#x7406;&#x5668;&#x5BF9;&#x8C61;&#x4F5C;&#x4E3A;&#x53C2;&#x6570;&#x88AB;&#x4F20;&#x5165;&#x3002;</li>
</ol>
<p>&#x5176;&#x4E2D; <code>Proxy.newProxyInstance()</code> &#x65B9;&#x6CD5;&#x5C01;&#x88C5;&#x4E86; 3~5 &#x6B65;&#x9AA4;&#x7684;&#x5B9E;&#x73B0;&#x3002;&#x4E0B;&#x9762;&#x4E00;&#x8282;&#x5C06;&#x4F1A;&#x7B80;&#x5355;&#x4ECB;&#x7ECD;&#x5B83;&#x7684;&#x539F;&#x7406;&#x3002;</p>
<h2 id="&#x52A8;&#x6001;&#x4EE3;&#x7406;&#x539F;&#x7406;">&#x52A8;&#x6001;&#x4EE3;&#x7406;&#x539F;&#x7406;</h2>
<p>&#x4E0B;&#x6765;&#x770B;&#x4E00;&#x4E0B; <code>Proxy.newProxyInstance()</code> &#x6E90;&#x7801;&#x3002;</p>
<pre><code class="lang-java">    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Object <span class="hljs-title">newProxyInstance</span><span class="hljs-params">(ClassLoader loader, Class&lt;?&gt;[] interfaces,
                                          InvocationHandler invocationHandler)</span>
            <span class="hljs-keyword">throws</span> IllegalArgumentException </span>{

        <span class="hljs-keyword">if</span> (invocationHandler == <span class="hljs-keyword">null</span>) {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NullPointerException(<span class="hljs-string">&quot;invocationHandler == null&quot;</span>);
        }
        Exception cause;
        <span class="hljs-keyword">try</span> {
            <span class="hljs-comment">// getProxyClass &#x83B7;&#x5F97;&#x4E0E;&#x6307;&#x5B9A;&#x7C7B;&#x88C5;&#x8F7D;&#x5668;&#x548C;&#x4E00;&#x7EC4;&#x63A5;&#x53E3;&#x76F8;&#x5173;&#x7684;&#x4EE3;&#x7406;&#x7C7B;&#x7C7B;&#x578B;&#x5BF9;&#x8C61;</span>
            <span class="hljs-comment">// getConstructor &#x901A;&#x8FC7;&#x53CD;&#x5C04;&#x83B7;&#x53D6;&#x6784;&#x9020;&#x51FD;&#x6570;&#x5BF9;&#x8C61;</span>
            <span class="hljs-comment">// newInstance &#x751F;&#x6210;&#x4EE3;&#x7406;&#x7C7B;&#x5B9E;&#x4F8B;</span>
            <span class="hljs-keyword">return</span> getProxyClass(loader, interfaces)
                    .getConstructor(InvocationHandler.class)
                    .newInstance(invocationHandler);
        } <span class="hljs-keyword">catch</span> (NoSuchMethodException e) {
            cause = e;
        } <span class="hljs-keyword">catch</span> (IllegalAccessException e) {
            cause = e;
        } <span class="hljs-keyword">catch</span> (InstantiationException e) {
            cause = e;
        } <span class="hljs-keyword">catch</span> (InvocationTargetException e) {
            cause = e;
        }
        AssertionError error = <span class="hljs-keyword">new</span> AssertionError();
        error.initCause(cause);
        <span class="hljs-keyword">throw</span> error;
    }
</code></pre>
<p>&#x6765;&#x770B;&#x4E00;&#x4E0B; <code>Proxy.getProxyClass()</code>&#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;&#xFF1A;</p>
<pre><code class="lang-java">    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Class&lt;?&gt; getProxyClass(ClassLoader loader, Class&lt;?&gt;... interfaces)
            <span class="hljs-keyword">throws</span> IllegalArgumentException {
        <span class="hljs-keyword">if</span> (loader == <span class="hljs-keyword">null</span>) {
            loader = ClassLoader.getSystemClassLoader();
        }

        <span class="hljs-keyword">if</span> (interfaces == <span class="hljs-keyword">null</span>) {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NullPointerException(<span class="hljs-string">&quot;interfaces == null&quot;</span>);
        }

        <span class="hljs-keyword">final</span> List&lt;Class&lt;?&gt;&gt; interfaceList = <span class="hljs-keyword">new</span> ArrayList&lt;Class&lt;?&gt;&gt;(interfaces.length);
        Collections.addAll(interfaceList, interfaces);

        <span class="hljs-keyword">final</span> Set&lt;Class&lt;?&gt;&gt; interfaceSet = <span class="hljs-keyword">new</span> HashSet&lt;Class&lt;?&gt;&gt;(interfaceList);
        <span class="hljs-keyword">if</span> (interfaceSet.contains(<span class="hljs-keyword">null</span>)) {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NullPointerException(<span class="hljs-string">&quot;interface list contains null: &quot;</span> + interfaceList);
        }

        <span class="hljs-keyword">if</span> (interfaceSet.size() != interfaces.length) {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(<span class="hljs-string">&quot;duplicate interface in list: &quot;</span> + interfaceList);
        }

        <span class="hljs-keyword">synchronized</span> (loader.proxyCache) {
            Class&lt;?&gt; proxy = loader.proxyCache.get(interfaceList);
            <span class="hljs-keyword">if</span> (proxy != <span class="hljs-keyword">null</span>) {
                <span class="hljs-keyword">return</span> proxy;
            }
        }

        String commonPackageName = <span class="hljs-keyword">null</span>;
        <span class="hljs-keyword">for</span> (Class&lt;?&gt; c : interfaces) {
            <span class="hljs-comment">// &#x5982;&#x679C;&#x4E0D;&#x662F;interface&#xFF0C;&#x629B;&#x51FA;&#x5F02;&#x5E38;</span>
            <span class="hljs-keyword">if</span> (!c.isInterface()) {
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(c + <span class="hljs-string">&quot; is not an interface&quot;</span>);
            }
            <span class="hljs-comment">// &#x5224;&#x65AD;&#x662F;&#x5426;&#x5BF9;&#x7C7B;&#x88C5;&#x8F7D;&#x5668;&#x53EF;&#x89C1;</span>
            <span class="hljs-keyword">if</span> (!isVisibleToClassLoader(loader, c)) {
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(c + <span class="hljs-string">&quot; is not visible from class loader&quot;</span>);
            }
            <span class="hljs-keyword">if</span> (!Modifier.isPublic(c.getModifiers())) {
                String packageName = c.getPackageName$();
                <span class="hljs-keyword">if</span> (packageName == <span class="hljs-keyword">null</span>) {
                    packageName = <span class="hljs-string">&quot;&quot;</span>;
                }
                <span class="hljs-keyword">if</span> (commonPackageName != <span class="hljs-keyword">null</span> &amp;&amp; !commonPackageName.equals(packageName)) {
                    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> IllegalArgumentException(
                            <span class="hljs-string">&quot;non-public interfaces must be in the same package&quot;</span>);
                }
                commonPackageName = packageName;
            }
        }

        List&lt;Method&gt; methods = getMethods(interfaces);
        Collections.sort(methods, ORDER_BY_SIGNATURE_AND_SUBTYPE);
        validateReturnTypes(methods);
        List&lt;Class&lt;?&gt;[]&gt; exceptions = deduplicateAndGetExceptions(methods);

        ArtMethod[] methodsArray = <span class="hljs-keyword">new</span> ArtMethod[methods.size()];
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; methodsArray.length; i++) {
            methodsArray[i] = methods.get(i).getArtMethod();
        }
        Class&lt;?&gt;[][] exceptionsArray = exceptions.toArray(<span class="hljs-keyword">new</span> Class&lt;?&gt;[exceptions.size()][]);

        <span class="hljs-comment">// &#x786E;&#x5B9A;&#x7C7B;&#x540D;</span>
        String baseName = commonPackageName != <span class="hljs-keyword">null</span> &amp;&amp; !commonPackageName.isEmpty()
                ? commonPackageName + <span class="hljs-string">&quot;.$Proxy&quot;</span>
                : <span class="hljs-string">&quot;$Proxy&quot;</span>;

        Class&lt;?&gt; result;
        <span class="hljs-keyword">synchronized</span> (loader.proxyCache) {
            result = loader.proxyCache.get(interfaceSet);
            <span class="hljs-keyword">if</span> (result == <span class="hljs-keyword">null</span>) {
                String name = baseName + nextClassNameIndex++;
                <span class="hljs-comment">// &#x751F;&#x6210;&#x4EE3;&#x7406;&#x7C7B;</span>
                result = generateProxy(name, interfaces, loader, methodsArray, exceptionsArray);
                <span class="hljs-comment">// &#x653E;&#x5165;&#x7F13;&#x5B58;</span>
                loader.proxyCache.put(interfaceList, result);
            }
        }

        <span class="hljs-keyword">return</span> result;
    }
</code></pre>
<h2 id="&#x5C0F;&#x7ED3;">&#x5C0F;&#x7ED3;</h2>
<p>Proxy &#x867D;&#x7136;&#x4F7F;&#x7528;&#x8D77;&#x6765;&#x5F88;&#x65B9;&#x4FBF;&#xFF0C;&#x4F46;&#x5B83;&#x7684;&#x8BBE;&#x8BA1;&#x4F7F;&#x5F97;&#x5B83;&#x53EA;&#x80FD;&#x652F;&#x6301; interface &#x7684;&#x4EE3;&#x7406;&#xFF0C;Java &#x7684;&#x7EE7;&#x627F;&#x673A;&#x5236;&#x6CE8;&#x5B9A;&#x4E86;&#x52A8;&#x6001;&#x4EE3;&#x7406;&#x7C7B;&#x65E0;&#x6CD5;&#x5B9E;&#x73B0;&#x5BF9; class &#x7684;&#x52A8;&#x6001;&#x4EE3;&#x7406;&#xFF0C;&#x56E0;&#x4E3A;&#x591A;&#x7EE7;&#x627F;&#x5728; Java &#x4E2D;&#x672C;&#x8D28;&#x4E0A;&#x5C31;&#x884C;&#x4E0D;&#x901A;&#x3002;&#x56E0;&#x4E3A;&#x4EE3;&#x7406;&#x7C7B;&#x9700;&#x8981;&#x7EE7;&#x627F; Proxy &#x7C7B;&#xFF0C;&#x8FD9;&#x6837;&#x5B83;&#x5C31;&#x4E0D;&#x80FD;&#x518D;&#x7EE7;&#x627F;&#x5176;&#x4ED6;&#x7684;&#x7C7B;&#x4E86;&#x3002;&#x56E0;&#x6B64;&#x4E0D;&#x652F;&#x6301;&#x5B9E;&#x73B0;&#x7C7B;&#x7684;&#x4EE3;&#x7406;&#xFF0C;&#x53EA;&#x652F;&#x6301;&#x63A5;&#x53E3;&#x7684;&#x4EE3;&#x7406;&#x3002;
&#x4F46;&#x662F;&#x76EE;&#x524D;&#x4E5F;&#x6709;&#x4E86;&#x9488;&#x5BF9; class &#x7684;&#x52A8;&#x6001;&#x4EE3;&#x7406;&#x89E3;&#x51B3;&#x65B9;&#x6848;&#xFF0C;&#x6BD4;&#x5982; CGLib&#x3002;</p>
<h2 id="&#x76F8;&#x5173;&#x63A8;&#x8350;&#x6587;&#x7AE0;">&#x76F8;&#x5173;&#x63A8;&#x8350;&#x6587;&#x7AE0;</h2>
<p><a href="https://www.ibm.com/developerworks/cn/java/j-lo-proxy1/" target="_blank">https://www.ibm.com/developerworks/cn/java/j-lo-proxy1/</a>
<a href="http://blog.csdn.net/chjttony/article/details/7934776" target="_blank">http://blog.csdn.net/chjttony/article/details/7934776</a>
<a href="http://blog.csdn.net/rock_ray/article/details/22491763" target="_blank">http://blog.csdn.net/rock_ray/article/details/22491763</a>
<a href="http://rejoy.iteye.com/blog/1627405" target="_blank">http://rejoy.iteye.com/blog/1627405</a>
<a href="http://www.cnblogs.com/xiaoluo501395377/p/3383130.html" target="_blank">http://www.cnblogs.com/xiaoluo501395377/p/3383130.html</a></p>

                                
                                </section>
                            
    </div>
    <div class="search-results">
        <div class="has-results">
            
            <h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
            <ul class="search-results-list"></ul>
            
        </div>
        <div class="no-results">
            
            <h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
            
        </div>
    </div>
</div>

                        </div>
                    </div>
                
            </div>

            
                
                <a href="java-basic-concurrent-map-collection.html" class="navigation navigation-prev " aria-label="Previous page: Java 基础 -- 并发集合的使用">
                    <i class="fa fa-angle-left"></i>
                </a>
                
                
                <a href="java-basic-try-catch-finally.html" class="navigation navigation-next " aria-label="Next page: Java 基础 -- 深入理解 try catch finally">
                    <i class="fa fa-angle-right"></i>
                </a>
                
            
        
    </div>

    <script>
        var gitbook = gitbook || [];
        gitbook.push(function() {
            gitbook.page.hasChanged({"page":{"title":"Java InvocationHandler 实现动态代理","level":"1.1.6","depth":2,"next":{"title":"Java 基础 -- 深入理解 try catch finally","level":"1.1.7","depth":2,"path":"source/Java/java-basic-try-catch-finally.md","ref":"source/Java/java-basic-try-catch-finally.md","articles":[]},"previous":{"title":"Java 基础 -- 并发集合的使用","level":"1.1.5","depth":2,"path":"source/Java/java-basic-concurrent-map-collection.md","ref":"source/Java/java-basic-concurrent-map-collection.md","articles":[]},"dir":"ltr"},"config":{"plugins":["expandable-chapters","livereload"],"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"pluginsConfig":{"expandable-chapters":{},"livereload":{},"highlight":{},"search":{},"lunr":{"maxIndexSize":1000000,"ignoreSpecialCharacters":false},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"fontsettings":{"theme":"white","family":"sans","size":2},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false}},"theme":"default","pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":56,"bottom":56}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"variables":{},"title":"寒江蓑笠的博客","gitbook":"*"},"file":{"path":"source/Java/java-dynamic-proxy-invocationhandler-demo.md","mtime":"2022-05-17T10:49:59.392Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2022-05-17T10:54:58.084Z"},"basePath":"../..","book":{"language":""}});
        });
    </script>
</div>

        
    <script src="../../gitbook/gitbook.js"></script>
    <script src="../../gitbook/theme.js"></script>
    
        
        <script src="../../gitbook/gitbook-plugin-expandable-chapters/expandable-chapters.js"></script>
        
    
        
        <script src="../../gitbook/gitbook-plugin-livereload/plugin.js"></script>
        
    
        
        <script src="../../gitbook/gitbook-plugin-search/search-engine.js"></script>
        
    
        
        <script src="../../gitbook/gitbook-plugin-search/search.js"></script>
        
    
        
        <script src="../../gitbook/gitbook-plugin-lunr/lunr.min.js"></script>
        
    
        
        <script src="../../gitbook/gitbook-plugin-lunr/search-lunr.js"></script>
        
    
        
        <script src="../../gitbook/gitbook-plugin-sharing/buttons.js"></script>
        
    
        
        <script src="../../gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
        
    

    </body>
</html>

